package com.module.frame.base

import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity

/**
 * @author bsnl_yanxuwen
 * @date 2021/1/21 9:35
 * Description :
 */
abstract class AppBaseActivity : AppCompatActivity() {
    private var autoHideSoft //自动关闭软键盘
            = false

    /**
     * 获取布局 Id
     *
     * @return
     */

    @LayoutRes
    protected abstract fun getLayoutId(): Int

    /**
     * 获取 Intent 数据
     */
    protected abstract fun getIntent(intent: Intent)

    /**
     * 初始化View的代码写在这个方法中
     */
    protected abstract fun initView()

    /**
     * 初始化监听器的代码写在这个方法中
     */
    protected abstract fun initListener()

    /**
     * 初始数据的代码写在这个方法中，用于从服务器获取数据
     */
    protected abstract fun initData()
    override fun onCreate(savedInstanceState: Bundle?) {
        val intent = intent
        intent?.let { getIntent(it) }
        super.onCreate(savedInstanceState)
        setContentView()
        initView()
        initListener()
        Handler(Looper.getMainLooper()).post { initData() }
    }

    protected open fun setContentView() {
        if (getLayoutId() != 0) {
            setContentView(getLayoutId())
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN && autoHideSoft) {
            // 获得当前得到焦点的View，一般情况下就是EditText（特殊情况就是轨迹求或者实体案件会移动焦点）
            val v = currentFocus
            if (isShouldHideInput(v, ev)) {
                hideSoftInput(v!!.windowToken)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时没必要隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = (left
                    + v.getWidth())
            // 点击EditText的事件，忽略它。
            return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditView上，和用户用轨迹球选择其他的焦点
        return false
    }

    /**
     * 多种隐藏软件盘方法的其中一种
     *
     * @param token
     */
    private fun hideSoftInput(token: IBinder?) {
        if (token != null) {
            val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }

    fun setAutoHideSoft(autoHideSoft: Boolean) {
        this.autoHideSoft = autoHideSoft
    }
}